package com.maistars.spider.infrastructure.adapter;

import com.maistars.spider.common.util.HtmlUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.CookieStore;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.IOException;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author dhr
 * @date 2021/10/20 下午11:11
 */
@Slf4j
public class SeleniumAdapter {

    public static String appendHtmlContentToTagWithLazyTime(String chromeDriverPath,String url, long pageloadTimeout,long scriptTimeout,CookieStore cookieStore) throws IOException, InterruptedException {
        String pageSource = chromeDownload(chromeDriverPath,url,pageloadTimeout,scriptTimeout,cookieStore);
        Document document = Jsoup.parse(pageSource);
        Elements headElements = document.getElementsByTag("head");
        for (Element element : headElements) {
            Elements childElements = element.children();
            if (childElements.size() != 0) {
                String domainName = HtmlUtil.getDomainNameAndProtocol(url);
//                childElements.first().before("<base href='" + domainName + "'/>");
                break;
            }
        }
//        Elements aElements = document.getElementsByTag(tag);
//        for (Element element : aElements) {
//            Elements childElements = element.children();
//            if (childElements.size() != 0) {
//                childElements.wrap(prefix + postfix);
//            }
//        }
        return HtmlUtil.handleLinkSingleAndDoubleSlash(document.html(),url);
    }

    public static CookieStore login(String chromeDriverPath,String url){
        // 指定chrome driver的获取地址
        System.setProperty("webdriver.chrome.driver", chromeDriverPath);

        //设置chrome headless模式为true
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--headless");
        options.addArguments("--window-size=1920x1080");

        //实例化webdriver的对象，以headless模式启动谷歌浏览器
        WebDriver driver = new ChromeDriver(options);

        // 加载url
        driver.get(url);
        // 等待加载完成
        driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
        WebElement login = driver.findElement(By.className("login"));
        login.click();

        // 获取页面元素
        WebElement elemUsername = driver.findElement(By.name("email"));
        elemUsername.sendKeys("15261418438");
        WebElement elemPassword = driver.findElement(By.name("password"));
        elemPassword.sendKeys("7758521dfg");
        WebElement btn = driver.findElement(By.cssSelector(".mail-login .btn"));
        btn.click();

        Set<Cookie> cookies = driver.manage().getCookies();

        Iterator<Cookie> itr = cookies.iterator();

        CookieStore cookieStore = new BasicCookieStore();

        while (itr.hasNext()) {
            Cookie cookie = itr.next();
            BasicClientCookie bcco = new BasicClientCookie(cookie.getName(), cookie.getValue());
            bcco.setDomain(cookie.getDomain());
            bcco.setPath(cookie.getPath());
            cookieStore.addCookie(bcco);
        }

        //退出浏览器
        driver.quit();
        return cookieStore;
    }

    public static void loginInternal(WebDriver driver,String url){
        // 加载url
        driver.get(url);
        // 等待加载完成
        driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
        WebElement login = driver.findElement(By.cssSelector(".nav-login .login"));
        login.click();

        // 获取页面元素
        WebElement elemUsername = driver.findElement(By.name("email"));
        elemUsername.sendKeys("15261418438");
        WebElement elemPassword = driver.findElement(By.name("password"));
        elemPassword.sendKeys("7758521dfg");
        WebElement btn = driver.findElement(By.cssSelector(".mail-login .btn"));
        btn.click();
    }

    public static String chromeDownload(String chromeDriverPath,String url,long pageloadTimeout,long scriptTimeout,CookieStore cookieStore) throws InterruptedException {
        // 指定chrome driver的获取地址
        System.setProperty("webdriver.chrome.driver", chromeDriverPath);

        //设置chrome headless模式为true
        ChromeOptions options = new ChromeOptions();
//        options.addArguments("--headless");
        options.addArguments("--window-size=1920x1080");

        //实例化webdriver的对象，以headless模式启动谷歌浏览器
        WebDriver driver = new ChromeDriver(options);

//        loginInternal(driver,url);

        //通过对象driver调用具体的get方法来打开网页
        driver.get(url);

//        List<org.apache.http.cookie.Cookie> cookieList = cookieStore.getCookies();
//        for(org.apache.http.cookie.Cookie cookie:cookieList){
//            Cookie cookie1 = new Cookie(cookie.getName(),cookie.getValue());
//            driver.manage().addCookie(cookie1);
//        }
//
//        //通过对象driver调用具体的get方法来打开网页
//        driver.navigate().refresh();


        // 等待加载完成
        driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);

        // 页面载入超时时间
        driver.manage().timeouts().pageLoadTimeout(pageloadTimeout, TimeUnit.SECONDS);

        // 脚本载入超时时间
        driver.manage().timeouts().setScriptTimeout(scriptTimeout, TimeUnit.SECONDS);

        String pageSource = getDynamicPageSource(driver,8000);

        //退出浏览器
        driver.close();
        driver.quit();
        return pageSource;
    }

    private static String getDynamicPageSource(WebDriver webDriver,int scrollSize) throws InterruptedException {
        //设置浏览器的宽高
        Dimension dimension = new Dimension(1000, scrollSize);
        webDriver.manage().window().setSize(dimension);
        String html = "";
        //获取JS执行器，可以执行js代码来控制页面
        JavascriptExecutor driver_js= ((JavascriptExecutor) webDriver);
        //获取页面的高度
        long scrollHeight = (long) driver_js.executeScript("return document.body.scrollHeight");
        //因为要模拟鼠标滚动浏览网页的效果，所以设置了每次滚动的高度，然后通过整个页面的高度计算出股东的次数
        long loopNum = scrollHeight/scrollSize;
        loopNum = loopNum+1;
        for(int i =0 ; i < loopNum; i++){
            long start = i*Long.valueOf(scrollSize);
            long end = (i+1)*Long.valueOf(scrollSize);
            //根据滚动的次数，依次滚动页面，为了图片能加载完全，停留1秒钟
            driver_js.executeScript("scroll("+start+","+end+")");
            Thread.sleep(3000);
        }
        //返回页面全部内容
        html = (String)driver_js.executeScript("return document.documentElement.outerHTML");
        return html;
    }

    /**
     *  自定义显式等待
     * @param driver
     * @param by
     * @return
     */
    private static WebElement webelementExplicitWait(WebDriver driver, By by)
    {
        return (new WebDriverWait(driver, 10)) .until(
                new ExpectedCondition< WebElement>(){
                    @Override
                    public WebElement apply(WebDriver d) {
                        return d.findElement(by);
                    }
                }
        );
    }
    /**
     *  判断元素是否存在
     * @param driver
     * @param by
     * @return
     */
    private static boolean isPresentElement(WebDriver driver,By by)
    {
        try {
            driver.findElement(by);
            return true;
        } catch (NoSuchElementException e) {
            return false;
        }catch(Exception e){
            return false;
        }
    }

    public static void main(String[] args){
        SeleniumAdapter.login("/Users/dhr/Downloads/chromedriver_1","https://huaban.com/");
    }

}
